/*
 * tcp_recv_cmd.c
 *
 *  Created on: May 10, 2016
 *      Author: Alan Wang
 */

#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "tcp_recv_cmd.h"
#include "tcp_helper.h"
#include "json_helper.h"
#include "../conf/dev_conf.h"
#include "../../app/gvar.h"
#include "../../util/log.h"
#include "../sqldb/db_helper.h"

#define TCP_RECV_SOCKET_PORT 12346

#define CMD_ID_SENDMASTERINFO     1
#define CMD_ID_SENDWIFIINFO       2
#define CMD_ID_MODIFYDEVICEWIFI   3
#define CMD_ID_GETDEVICEUSERLIST  4
#define CMD_ID_DELETEDEVICEUSER   5
#define CMD_ID_UNBINDDEVICE   	  6
#define CMD_ID_GETDEVICESTATUS    7

int serv_recv_socket_fd;
int client_recv_socket_fd;
int is_tcp_recv_run;

void tcp_recv_accept_client_connect();//private method
int tcp_recv_handle_request(char* json_str);//private method

int handle_sendMasterInfo(char* json_str);
int handle_sendWifiInfo(char* json_str);
int handle_modifyDeviceWifi(char* json_str);
int handle_getDeviceUserList(char* json_str);
int handle_deleteDeviceUser(char* json_str);
int handle_unbindDevice(char* json_str);
int handle_getDeviceStatus(char* json_str);

void start_tcp_recv_cmd_server(){
	LogStr("tcp_recv_start_cmd_server()!--->>> \n ");
	is_tcp_recv_run = 1;
	serv_recv_socket_fd = init_tcp_socket(TCP_RECV_SOCKET_PORT);
	if(serv_recv_socket_fd <= 0){
		Log("init receive server socket failed!--->>socket_fd = d%\n", serv_recv_socket_fd);
	}
	Log("init receive server socket success!--->>socket_fd = d%\n", serv_recv_socket_fd);
	pthread_t sub_thread;
	int ret = pthread_create(&sub_thread, NULL, (void *)tcp_recv_accept_client_connect, NULL);
	if(ret == -1){
		LogStr("creat receive server sub thread failed! \n ");
	}
}


void tcp_recv_accept_client_connect(){
	LogStr("tcp_recv_accept_client_connect()--->>>>\n");
	while(is_tcp_recv_run){
		LogStr("tcp receive server socket accept before--->>>\n");
		client_recv_socket_fd = accept(serv_recv_socket_fd, NULL, NULL);
		Log("tcp receive server socket accept after--->>>client_socket_fd = %d\n", client_recv_socket_fd);
		if(client_recv_socket_fd == 0) {
			LogStr("tcp receive server socket accept client failed !\n");
			continue;
		}else if(client_recv_socket_fd < 0){
			LogStr("tcp receive server socket accept client failed !\n");
			return;
		}
		while(is_tcp_recv_run){
			char* json_str;
			int content_len = recv_data_from_client(&json_str, client_recv_socket_fd);
			Log("---->>>>>content_len =  %d \n", content_len);
			if(content_len <= 1){
				free(json_str);
				json_str = NULL;
				break;
			}
			int ret = tcp_recv_handle_request(json_str);
			free(json_str);
			json_str = NULL;
			if(ret < 0){
				break;
			}
		}
		close(client_recv_socket_fd);
		Log("tcp receive server --->>> close client socket ---->>> client_recv_socket_fd = %d\n", client_recv_socket_fd);
	}
	close(serv_recv_socket_fd);
	Log("tcp receive server --->>> close server socket ---->>> serv_recv_socket_fd = %d\n", serv_recv_socket_fd);
}



int handle_sendMasterInfo(char* json_str){
	ReqSendMasterInfo req_sendMasterInfo;
	int status;
	char* rep_json_data;
	int send_len = 0;
	status = parse_req_for_deviceMasterId(&req_sendMasterInfo, json_str);
	if(status != 1){//parse json error response the error info to client
		rep_json_data = get_json_str_of_error_sendMasterInfo(
						ERR_CODE_SENDMASTERINFO_OF_COMMON_FAILED,
						ERR_MSG_SENDMASTERINFO_OF_COMMON_FAILED);
		send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
		free(rep_json_data);
		Log("send_len =  %d \n", send_len);
		return send_len;
	}

	Log("handle_sendMasterInfo()--->>>id =  %d \n", req_sendMasterInfo.req_base.id);
	Log("handle_sendMasterInfo()--->>>method =  %s \n", req_sendMasterInfo.req_base.method);
	Log("handle_sendMasterInfo()--->>>deviceMasterId =  %d \n", req_sendMasterInfo.dev_master_id);

	status = set_dev_master_id(req_sendMasterInfo.dev_master_id);
	if(status == 1){
		rep_json_data = get_json_str_of_rep_sendMasterInfo(status);
	}else{
		rep_json_data = get_json_str_of_error_sendMasterInfo(
			ERR_CODE_SENDMASTERINFO_OF_COMMON_FAILED,
			ERR_MSG_SENDMASTERINFO_OF_COMMON_FAILED);
	}
	send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
	free(rep_json_data);
	Log("send_len =  %d \n", send_len);
	return send_len;
}



int handle_sendWifiInfo(char* json_str){
	ReqSendWifiInfo req_sendWifiInfo;
	int status = 0;
	char* rep_json_data;
	int send_len;
	status = parse_req_for_sendWifiInfo(&req_sendWifiInfo, json_str);
	if(status != 1){//parse json error response the error info to client
		rep_json_data = get_json_str_of_error_sendWifiInfo(
				ERR_CODE_SENDWIFIINFO_OF_COMMON_FAILED,
				ERR_MSG_SENDWIFIINFO_OF_COMMON_FAILED);
		send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
		free(rep_json_data);
		Log("send_len =  %d \n", send_len);
		return send_len;
	}

	Log("id =  %d \n", req_sendWifiInfo.req_base.id);
	Log("method =  %s \n", req_sendWifiInfo.req_base.method);
	Log("deviceMasterId =  %d \n", req_sendWifiInfo.dev_master_id);
	Log("list_len =  %d \n", req_sendWifiInfo.list_len);

	int i = 0;
	for(; i < req_sendWifiInfo.list_len; i++){
		Log("wifi_area_id =  %d \n", req_sendWifiInfo.wifi_list->wifi_area_id);
		Log("wifi_id =  %d \n", req_sendWifiInfo.wifi_list->wifi_id);
		Log("wifi_latitude =  %f \n", req_sendWifiInfo.wifi_list->wifi_latitude);
		Log("wifi_longitude =  %f \n", req_sendWifiInfo.wifi_list->wifi_longitude);
		Log("wifi_mac =  %s \n", req_sendWifiInfo.wifi_list->wifi_mac);
		Log("wifi_matser_id =  %d \n", req_sendWifiInfo.wifi_list->wifi_matser_id);
		Log("wifi_password =  %s \n", req_sendWifiInfo.wifi_list->wifi_password);
		Log("wifi_ssid =  %s \n", req_sendWifiInfo.wifi_list->wifi_ssid);
		LogStr("<<<<<<<---------------------->>>>>>\n");
	}

	//TODO : save the received wifiInfo list
	Log("g_dev_conf.dev_master_id =  %d \n", g_dev_conf.dev_master_id);
	if(g_dev_conf.dev_master_id == req_sendWifiInfo.dev_master_id){
		//TODO :save the wifi list to database
		status = db_insert_wifilist(req_sendWifiInfo.wifi_list, req_sendWifiInfo.list_len);
		rep_json_data = get_json_str_of_rep_sendWifiInfo(status);
	}else{//master id unmatched,permission denied!
		rep_json_data = get_json_str_of_error_sendWifiInfo(
				ERR_CODE_SENDWIFIINFO_OF_PERMISSION_DENIED,
				ERR_MSG_SENDWIFIINFO_OF_PERMISSION_DENIED);
	}
	send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
	free(rep_json_data);
	Log("send_len =  %d \n", send_len);
	return send_len;
}

int handle_modifyDeviceWifi(char* json_str){
	ReqModifyDeviceWifi req_modifyDeviceWifi;
	int status = 0;
	char* rep_json_data;
	int send_len;
	status = parse_req_for_modifyDeviceWifi(&req_modifyDeviceWifi, json_str);
	if(status != 1){//parse json error response the error info to client
		rep_json_data = get_json_str_of_error_modifyDeviceWifi(
				ERR_CODE_MODIFYDEVICEWIFI_OF_COMMON_FAILED,
				ERR_MSG_MODIFYDEVICEWIFI_OF_COMMON_FAILED);
		send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
		free(rep_json_data);
		Log("send_len =  %d \n", send_len);
		return send_len;
	}


	Log("id =  %d \n", req_modifyDeviceWifi.req_base.id);
	Log("method =  %s \n", req_modifyDeviceWifi.req_base.method);
	Log("deviceMasterId =  %d \n", req_modifyDeviceWifi.dev_master_id);
	Log("ssid =  %s \n", req_modifyDeviceWifi.ssid);
	Log("password =  %s \n", req_modifyDeviceWifi.password);

	//TODO : modify the device wifi's ssid and password
	if(g_dev_conf.dev_master_id == req_modifyDeviceWifi.dev_master_id){
		//TODO :save the wifi list to database
		status = set_dev_wifi_info(req_modifyDeviceWifi.ssid, req_modifyDeviceWifi.password);
		rep_json_data = get_json_str_of_rep_modifyDeviceWifi(status);
	}else{//master id unmatched,permission denied!
		rep_json_data = get_json_str_of_error_modifyDeviceWifi(
				ERR_CODE_MODIFYDEVICEWIFI_OF_PERMISSION_DENIED,
				ERR_MSG_MODIFYDEVICEWIFI_OF_PERMISSION_DENIED);
	}
	send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
	free(rep_json_data);
	Log("send_len =  %d \n", send_len);
	return send_len;
}

int handle_getDeviceUserList(char* json_str){
	ReqGetDeviceUserList req_getDeviceUserList;
	int status = 0;
	char* rep_json_data;
	int send_len;
	status = parse_req_for_getDeviceUserList(&req_getDeviceUserList, json_str);
	if(status != 1){//parse json error response the error info to client
		rep_json_data = get_json_str_of_error_getDeviceUserList(
				ERR_CODE_GETDEVICEUSERLIST_OF_COMMON_FAILED,
				ERR_MSG_GETDEVICEUSERLIST_OF_COMMON_FAILED);
		send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
		free(rep_json_data);
		Log("send_len =  %d \n", send_len);
		return send_len;
	}

	Log("id =  %d \n", req_getDeviceUserList.req_base.id);
	Log("method =  %s \n", req_getDeviceUserList.req_base.method);
	Log("deviceMasterId =  %d \n", req_getDeviceUserList.dev_master_id);

	if(g_dev_conf.dev_master_id == req_getDeviceUserList.dev_master_id){
		status = 1;
		//TODO : query the connected user device list

		DeviceUserInfo dev_usr_list[2];
		strcpy(dev_usr_list[0].name, "Tp-Link_09866");
		strcpy(dev_usr_list[0].mac, "00:0c:29:39:f4:8e");
		strcpy(dev_usr_list[1].name, "Tp-Link_09865");
		strcpy(dev_usr_list[1].mac, "00:0c:29:39:f4:8e");
		rep_json_data = get_json_str_of_rep_getDeviceUserList(dev_usr_list, 2);
	}else{
		rep_json_data = get_json_str_of_error_getDeviceUserList(
				ERR_CODE_GETDEVICEUSERLIST_OF_PERMISSION_DENIED,
				ERR_MSG_GETDEVICEUSERLIST_OF_PERMISSION_DENIED);
	}
	send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
	free(rep_json_data);
	Log("send_len =  %d \n", send_len);
	return send_len;
}

int handle_deleteDeviceUser(char* json_str){
	ReqDeleteDeviceUser req_deqDeleteDeviceUser;
	int status = 0;
	char* rep_json_data;
	int send_len;
	status = parse_req_for_deleteDeviceUser(&req_deqDeleteDeviceUser, json_str);
	if(status != 1){//parse json error response the error info to client
		rep_json_data = get_json_str_of_error_deleteDeviceUser(
				ERR_CODE_DELETEDEVICEUSER_OF_COMMON_FAILED,
				ERR_MSG_DELETEDEVICEUSER_OF_COMMON_FAILED);
		send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
		free(rep_json_data);
		Log("send_len =  %d \n", send_len);
		return send_len;
	}

	Log("id =  %d \n", req_deqDeleteDeviceUser.req_base.id);
	Log("method =  %s \n", req_deqDeleteDeviceUser.req_base.method);
	Log("deviceMasterId =  %d \n", req_deqDeleteDeviceUser.dev_master_id);
	Log("user_mac =  %s \n", req_deqDeleteDeviceUser.user_mac);

	if(g_dev_conf.dev_master_id == req_deqDeleteDeviceUser.dev_master_id){
		//TODO : delete the connected user device
		status = 1;

		rep_json_data = get_json_str_of_rep_deleteDeviceUser(status);
	}else{
		rep_json_data = get_json_str_of_error_deleteDeviceUser(
				ERR_CODE_DELETEDEVICEUSER_OF_PERMISSION_DENIED,
				ERR_MSG_DELETEDEVICEUSER_OF_PERMISSION_DENIED);
	}
	send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
	free(rep_json_data);
	Log("send_len =  %d \n", send_len);
	return send_len;
}

int handle_unbindDevice(char* json_str){
	ReqUnbindDevice req_unbindDevice;
	int status = 0;
	char* rep_json_data;
	int send_len;
	status = parse_req_for_unbindDevice(&req_unbindDevice, json_str);
	if(status != 1){//parse json error response the error info to client
		rep_json_data = get_json_str_of_error_unbindDevice(
				ERR_CODE_UNBINDDEVICE_OF_COMMON_FAILED,
				ERR_MSG_UNBINDDEVICE_OF_COMMON_FAILED);
		send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
		free(rep_json_data);
		Log("send_len =  %d \n", send_len);
		return send_len;
	}
	Log("id = %d\n", req_unbindDevice.req_base.id);
	Log("method = %s\n", req_unbindDevice.req_base.method);
	Log("dev_master_id = %d\n", req_unbindDevice.dev_master_id);
	Log("devr_mac = %s\n", req_unbindDevice.dev_mac);
	Log("g_dev_conf.devr_mac = %s\n", g_dev_conf.dev_mac);

	if(g_dev_conf.dev_master_id == req_unbindDevice.dev_master_id
			&& (strcmp(g_dev_conf.dev_mac, req_unbindDevice.dev_mac) == 0)){
		//TODO : unbind the device
		LogStr("execute unbind device operation! \n");
		status = 1;

		rep_json_data = get_json_str_of_rep_unbindDevice(status);
	}else{
		rep_json_data = get_json_str_of_error_unbindDevice(
				ERR_CODE_UNBINDDEVICE_OF_COMMON_FAILED,
				ERR_MSG_UNBINDDEVICE_OF_COMMON_FAILED);
	}
	send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
	free(rep_json_data);
	Log("send_len =  %d \n", send_len);
	return send_len;
}

int handle_getDeviceStatus(char* json_str){
	ReqGetDeviceStatus req_getDeviceStatus;
	int status = 0;
	char* rep_json_data;
	int send_len;
	status = parse_req_for_getDeviceStatus(&req_getDeviceStatus, json_str);
	if(status != 1){//parse json error response the error info to client
		rep_json_data = get_json_str_of_error_getDeviceStatus(
				ERR_CODE_GETDEVICESTATUS_OF_COMMON_FAILED,
				ERR_MSG_GETDEVICESTATUS_OF_COMMON_FAILED);
		send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
		free(rep_json_data);
		Log("send_len =  %d \n", send_len);
		return send_len;
	}
	Log("id = %d\n", req_getDeviceStatus.req_base.id);
	Log("method = %s\n", req_getDeviceStatus.req_base.method);

	//TODO :get device status
	DeviceStatus dev_status;
	dev_status.net_status = NET_OTHERERROR;
	dev_status.work_status = WORK_NOBOUND;
	rep_json_data = get_json_str_of_rep_getDeviceStatus(dev_status);
	send_len = send_data_to_client(client_recv_socket_fd, rep_json_data);
	free(rep_json_data);
	Log("send_len =  %d \n", send_len);
	return send_len;
}

int tcp_recv_handle_request(char* json_str){
	int send_len = -1;
	if(json_str == NULL){
		return send_len;
	}
	Log("json_str_len =  %d\n", strlen(json_str));
	//prt_pstr_in_hex(json_str, strlen(json_str));
	Log("json_str = %s\n", json_str);
	int cmd_id = parse_req_to_get_cmd_id(json_str);
	Log("cmd_id = %d\n", cmd_id);
	switch(cmd_id){
		case CMD_ID_SENDMASTERINFO:
			send_len = handle_sendMasterInfo(json_str);
			break;
		case CMD_ID_SENDWIFIINFO:
			send_len = handle_sendWifiInfo(json_str);
			break;
		case CMD_ID_MODIFYDEVICEWIFI:
			send_len = handle_modifyDeviceWifi(json_str);
			break;
		case CMD_ID_GETDEVICEUSERLIST:
			send_len = handle_getDeviceUserList(json_str);
			break;
		case CMD_ID_DELETEDEVICEUSER:
			send_len = handle_deleteDeviceUser(json_str);
			break;
		case CMD_ID_UNBINDDEVICE:
			send_len = handle_unbindDevice(json_str);
			break;
		case CMD_ID_GETDEVICESTATUS:
			send_len = handle_getDeviceStatus(json_str);
			break;
	}
	return send_len;
	//parse json string of client request
}



